package com.instpower.things.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.instpower.things.config.CmdEnum;
import com.instpower.things.config.Configs;
import com.instpower.things.helper.Checksum;
import com.instpower.things.helper.Utils;
import com.instpower.things.instpower.Connection;
import com.instpower.things.instpower.DeviceSession;
import com.instpower.things.instpower.DeviceSessionManager;
import com.instpower.things.transport.*;
import com.instpower.things.util.CabinetQueryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.nio.ByteBuffer;

/**
 * @ClassName CmdHandler
 * @Author: hellmash@gmail.com
 * @Date: 2020/3/24
 * @Version: 1.0.0
 * @Description: 常用设备指令
 *
 * {
 *     "cabinetSn":"xxxx",
 *     "cmd":"reboot"
 * }
 *
 * {
 *  *     "cabinetSn":"xxxx",
 *  *     "cmd":"host",
 *        "ip":"192.168.0.1",
 *        "port":"9105"
 *  * }
 */

public class CmdHandler implements MessageListener {

    private final static Logger logger = LoggerFactory.getLogger("CORE");

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public void onMessage(Message message) {
        try {
            JsonNode msg = objectMapper.readTree(message.getBody());

            String sn = msg.get("cabinetSn").asText();
            logger.debug("CMD SN:::()" + sn);
            if(null == msg.get("cmd"))
                return;
            String cmd = msg.get("cmd").asText().toLowerCase();


            //先做个重启指令，后续再说
            Response resp = new Response();
            Header header = header = new Header();
            if(cmd.equals(CmdEnum.REBOOT.val())) {
                String sessionId = msg.get("sessionId").asText();
                redisTemplate.opsForValue().set(String.format(Configs.CMD_REBOOT_KEY_PREF, sn), sessionId);
                header.setPtrol((byte) 0x02);
                header.setAddr(sn);
                header.setCommand(Configs.REBOOT_CMD);
                header.setLength((short) 2);
            }else if(cmd.equals(CmdEnum.SETTINGHOST.val())){
                header.setPtrol((byte) 0x02);
                header.setAddr(sn);
                header.setCommand(Configs.HOST_CMD);
                //读取队列里IP和端口信息
                String ip = msg.get("ip").asText();
                String port = msg.get("port").asText();
                MTData mDataR = new MTData();
                DataBuffer dataBuffer = new DataBuffer(7);
                DataBuffer ipBuffer = Utils.parseIp(ip);
                if(ipBuffer == null || port ==null)
                    return;
                dataBuffer.writeDataBuffer(ipBuffer);
                dataBuffer.writeShort(Short.parseShort(port));
                dataBuffer.writeByte(0x00);
                mDataR.setDatas(dataBuffer.readBytes(7));
                resp.setData(mDataR);
                header.setLength((short) (9));
            }else if(cmd.equals(CmdEnum.CABINET_QUERY.val())){
                logger.info("anker 机柜主动接受admin后台查询,sn:{}",sn);
                CabinetQueryUtil.cabinetQuery(sn);
                logger.info("anker 机柜主动接受admin后台查询结束,sn:{}",sn);
                return;
            }
            resp.setHeader(header);
            DataBuffer buffer = resp.encode();
            int checksum = Checksum.crc16(Checksum.CRC16_ANKER,
                    ByteBuffer.wrap(buffer.readByteArray(buffer.readableBytes())));

            //do release after read
            buffer.release();

            Ender ender = new Ender();
            ender.setChecksum(checksum);
            resp.setEnder(ender);

            DeviceSession session;
            session = DeviceSessionManager.getInstance().get(sn);
            if (null != session) {
                Connection connection = session.getMConnection();
                if(null != connection) {
                    connection.sendResponse(resp);
                }
            }
        }catch (Exception e){
            logger.error("下发指令异常:");
            logger.error(e.getLocalizedMessage(),e);
        }
    }
}
